{
 "metadata": {
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.4"
  },
  "orig_nbformat": 2,
  "kernelspec": {
   "name": "python374jvsc74a57bd02a7e95a32014fc1ccf24626d45a98c6e7b4373277259c22f47a91d487fc3e8a5",
   "display_name": "Python 3.7.4 64-bit ('base': conda)"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2,
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 登陆网易云\n",
    "import requests\n",
    "url = 'https://music.163.com/weapi/w/login/cellphone?csrf_token='\n",
    "headers = {\n",
    "    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36'\n",
    "}\n",
    "data = {\n",
    "'params': 'hXSELmnqGlCZo4Sps/nMNkQ/HecKkHeIv2EwUUgUUmJLOcZ+u+7TBLgeY3Mq88s/fcew1L9hgZcUjtM9PoO5XwQEIxKViweN8Jlvl0Arw4vMsOODciBTYSuiNzbVKYUaqpbnrjd9uiZPOgzVSjB3zCoosQWt06URydDoj7xcmGEQndPOqoovz4Gln+WTPqNv7wkbbSfwfMxNhLDLff2LU5o1REnunBagRGwbkXOiqW/+QUPcu6FZf4YhwABQEmhgC8YQrRFrobrMPdJH9oVJ78ssJfHYyYC6hpqAaiaQcZJtpA2EWJDZm8Pmg9TzND4clnetnj0z6r/gSMltzJlQc2HkU9wAR2P0ZJFVrTyGV5LLXRao15WRIngsaP3MNYWwcrtDvsJiTvXpph0IATN6B/Tn6SDokJcpcI6rGNNrHXtm3sT5EucCrulUEibiFqjF3tyaT+bEyrxrIYUmY6Ny7/Om8MvDlnWpfSVJUytXEiRH+qsNQ4DTP816Z9ZY5PfRLSDzs1wC4Rk8aqFRzTMq0iDq2OO++SFI/p0kqAqROB0=',\n",
    "'encSecKey':'88d8f7854cf930175c5811dc01f392d4f0085143b01d375c400074d5cf70041a99d8614b105f6eec9ea16594bd3d17012d0f12d960a72797a63ff0cac44bb0e6a953fbcfb7b37043c31249c49596b2d6197c06fe2007d97d11b5c3de15eb0db8dabb23b74b26d2ad19087f7c26ecc6ef6f465be0c7f38f2c1943dedceebf9dd7'\n",
    "}\n",
    "login_in = requests.post(url,headers=headers,data=data)\n",
    "print(login_in.status_code)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#  总的程序\n",
    "import requests\n",
    "import json\n",
    "import base64\n",
    "import random\n",
    "import time\n",
    "import re\n",
    "from Crypto.Cipher import AES\n",
    "from lxml import etree   \n",
    "\n",
    "cloudMusic = {}\n",
    "# cookie = login_in.cookies\n",
    "headers = {\n",
    "    'authority': 'music.163.com',\n",
    "    'sec-ch-ua': '^\\\\^',\n",
    "    'sec-ch-ua-mobile': '?0',\n",
    "    'upgrade-insecure-requests': '1',\n",
    "    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36',\n",
    "    'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',\n",
    "    'sec-fetch-site': 'same-origin',\n",
    "    'sec-fetch-mode': 'navigate',\n",
    "    'sec-fetch-dest': 'iframe',\n",
    "    'referer': 'https://music.163.com/',\n",
    "    'accept-language': 'zh-CN,zh;q=0.9',\n",
    "    'cookie': 'MUSIC_EMAIL_U=4ec00d0263276c70b71593cf95bc61008ba689fefc8b4f0810f90ab860ade29ac1f412922aaeb58126f03d53a23f3c63c3061cd18d77b7a0; _iuqxldmzr_=32; _ntes_nuid=d55c1aad64f1fe19f6c776a4842992df; _ntes_nnid=d55c1aad64f1fe19f6c776a4842992df,1618886346498; playliststatus=visible; NMTID=00Oi0mGPvWmNzsMnEt0iaTsD_qun14AAAF47SVU5A; WEVNSM=1.0.0; WNMCID=wllinz.1618886348390.01.0; WM_TID=KXIbApzjnDhEQBEARRdrhK33SWItABSB; NTES_YD_SESS=NRIO3h4EZ05.RLgdNkaFDkLgt2jkpM7FeClQ4fViOOZR0UVp0AITEqEmBfJZVihqwsIzkIm262CEvEhEI.xHYADedYPZQu9.PSIkoLspo7VlMjzsJnN5eWzry1xqBWgQyHgkBqZ2l_8_qW4fjfPdYWHmI18nfBqeXJ2u0ZWamCMykT6dFLqvt8tzOv_xVHEwOl4FU03HRbbqRguD11RLY_wETz51OZmE6QqLQWwMgdeuF; S_INFO=1618926254^|0^|3&80^#^#^|18571826829; P_INFO=18571826829^|1618926254^|1^|study^|00&99^|null&null&null^#US&null^#10^#0^#0^|&0^|null^|18571826829; OUTFOX_SEARCH_USER_ID_NCOO=1052844159.6756152; UM_distinctid=178f3c6f5ba936-083adbb9e12cc4-3f356b-144000-178f3c6f5bb8fa; hb_MA-BFF5-63705950A31C_source=ke.study.163.com; _antanalysis_s_id=1619004186597; playerid=46407284; ntes_kaola_ad=1; WM_NI=STAsyDxeqqOURrrdOwagwCY0mzLh^%^2BpxWaVQZg1E2dQfHqM5PFp6oPKL5xUeZz9XKgT5jyLj7lVPNIFywuAo^%^2BP9X7pocEHonRsEzlj1eC9^%^2Fa7BsjOYMIHVN^%^2Bdt3obezZPOXQ^%^3D; WM_NIKE=9ca17ae2e6ffcda170e2e6eed9bb64f2aea793ed7ebce78aa6c45a939b8babaa74f4ad9d8deb41fbb1e1a2d82af0fea7c3b92a918c8f94fc50bcbbbf92ce5f92aebe85ce7da3b9b9a4dc3cafa68489aa7cbc89afb7d452a5ef8bd3e75ba698bfaeb85c86b0fa90d34190ebb8b6e852bae798ace660f7b6b7ade93db08aa0afcc4ebba9bba2ee2194e798d8f365a19b8890ed5ab19bb68de93ba79df7d0e43d82ada6b0dc478b989aafaa70b8eda183e8729a9081b9d437e2a3; MUSIC_U=ab509875e76f4a371c02e25068c9597005947b73657916bb99a50007177d9b8f9cb4377b2d7ba249; __remember_me=true; __csrf=d59d0637131f54976adc993f9460f030; JSESSIONID-WYYY=uCZFxdJ3FyOQvgdS424wv3uet7lFNdSS^%^2FwqtQCUMenofJF5^%^5CCQpCwIfOV4MrUImiBwa^%^2BmOZ3Zf bB4jet^%^2B9i2XXHArpnOkr8W1V6DANDfekly^%^2BFS4DTlKF^%^2Fzw08gH8oM^%^2FNQ8rrp^%^2FCsVQefox2MfPFYNYHstStrBiFb2V7kxxRQ42A8HKP^%^3A1620043080203'\n",
    "}\n",
    "\n",
    "res = requests.get('https://music.163.com/discover/playlist/?cat=%E7%B2%A4%E8%AF%AD', headers=headers)      # 一页有35个歌单\n",
    "\n",
    "resxml = etree.HTML(res.text) # 解析源码\n",
    "elems = resxml.xpath('//*[@id=\"m-pl-container\"]/li[*]/p[1]/a/@href')\n",
    "base_url = 'https://music.163.com'\n",
    "listlinks = [base_url + elem for elem in elems]\n",
    "\n",
    "for listlink in listlinks:\n",
    "    r = requests.get(listlink,headers=headers)\n",
    "    rxml = etree.HTML(r.text)\n",
    "    songs = rxml.xpath('//ul[@class=\"f-hide\"]/li/a/@href')  \n",
    "    for song in songs:\n",
    "        songid = ''.join(re.findall(r\"\\d+\\.?\\d*\",song))     # 字符串,而不是列表\n",
    "\n",
    "        with open('songid log.txt','r',encoding='utf-8') as f_log:\n",
    "            ID = f_log.read()     #FileNotFoundError\n",
    "\n",
    "        if songid not in ID:    # 判断日志里是否有内容,没有就开始爬虫\n",
    "            with open('songid log.txt','a',encoding='utf-8') as f_log:    # 断点日志\n",
    "                f_log.write(str(songid))\n",
    "                f_log.write('\\n')\n",
    "            \n",
    "            # 爬取歌名和歌手\n",
    "            urlsong = 'https://music.163.com'+song\n",
    "            r_song = requests.get(urlsong,headers=headers)\n",
    "            rxml_song = etree.HTML(r_song.text)\n",
    "            cloudMusic['songName'] = rxml_song.xpath('//em[@class=\"f-ff2\"]/text()')\n",
    "            cloudMusic['singer'] = rxml_song.xpath('//p[@class=\"des s-fc4\"]/span/@title')\n",
    "\n",
    "            # 爬取热评\n",
    "\n",
    "            param2 = \"010001\"   \n",
    "            param3 = \"00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7b725152b3ab17a876aea8a5aa76d2e417629ec4ee341f56135fccf695280104e0312ecbda92557c93870114af6c9d05c4f7f0c3685b7a46bee255932575cce10b424d813cfe4875d3e82047b97ddef52741d546b8e289dc6935b3ece0462db0a22b8e7\"\n",
    "            param4 = \"0CoJUm6Qyw8W8jud\"\n",
    "\n",
    "            def AES_encrypt(text, key, iv):\n",
    "                pad = 16 - len(text) % 16\n",
    "                text = text + pad * chr(pad)\n",
    "                text = text.encode(\"utf-8\")\n",
    "                encryptor = AES.new(key.encode('utf-8'), AES.MODE_CBC, iv)\n",
    "                encrypt_text = encryptor.encrypt(text)\n",
    "                encrypt_text = base64.b64encode(encrypt_text)\n",
    "                return encrypt_text.decode('utf-8')\n",
    "\n",
    "            def asrsea(p1, p2, p3, p4):\n",
    "                res = {}\n",
    "                rand_num = \"aq9d7cvBOJ1tzj1o\"\n",
    "                vi = b\"0102030405060708\"\n",
    "                h_encText = AES_encrypt(p1, p4, vi)\n",
    "                h_encText = AES_encrypt(h_encText, rand_num, vi)\n",
    "                res[\"encText\"] = h_encText\n",
    "                res[\"encSecKey\"] = \"5dec9ded1d7223302cc7db8d7e0428b04139743ab7e3d451ae47837f34e66f9a86f63e45ef20d147c33d88530a6c3c9d9d88e38586b42ee30ce43fbf3283a2b10e3118b76e11d6561d80e33ae38deb96832b1a358665c0579b1576b21f995829d45fc43612eede2ac243c6ebb6c2d16127742f3ac913d3ac7d6026b44cee424e\"\n",
    "                return res\n",
    "\n",
    "            cloudMusic['Comment'] = []\n",
    "            for i in range(11):\n",
    "                curr_time = int(time.time() * 1000)\n",
    "                param1 = json.dumps(\n",
    "                    {\n",
    "                        \"csrf_token\": \"\",\n",
    "                        \"cursor\": \"%s\" % curr_time,\n",
    "                        \"offset\": str(i*20), \n",
    "                        \"orderType\": \"2\", \n",
    "                        \"pageNo\": str(i+1),\n",
    "                        \"pageSize\": \"20\", \n",
    "                        \"rid\": \"R_SO_4_%s\" % songid, \n",
    "                        \"threadId\": \"R_SO_4_%s\" % songid\n",
    "                    }\n",
    "                                    )\n",
    "\n",
    "                asrsea_res = asrsea(param1, param2, param3, param4)\n",
    "\n",
    "                url = \"https://music.163.com/weapi/comment/resource/comments/get?csrf_token=\"\n",
    "\n",
    "                param_data = {\"params\": asrsea_res[\"encText\"],\n",
    "                            \"encSecKey\": asrsea_res[\"encSecKey\"]}\n",
    "                rct = requests.post(url, headers=headers, data=param_data, verify=False)\n",
    "                print(rct.text)\n",
    "                # try:\n",
    "                    # if rct.json()['data']['hotComments'] is not 'null':\n",
    "                hotComments = rct.json()['data']['hotComments']\n",
    "                    # else :\n",
    "                    #     continue\n",
    "                for hotComment in hotComments:\n",
    "                    cloudMusic['Comment'].append(hotComment['content'])\n",
    "                # except(KeyError,TypeError):\n",
    "                #     print('评论为空')\n",
    "            data = json.dumps(cloudMusic,ensure_ascii=False).encode('utf-8').decode('utf-8') \n",
    "            with open('cloudMusic.json','a',encoding='utf-8') as file_obj:\n",
    "                file_obj.write(data)\n",
    "                file_obj.write('\\n')    #   考虑将其挪到try里面,防止写入没有评论的歌曲\n",
    "\n",
    "# # 参数与歌ID无关,且没有规则,如何解决? >> selenium抓取html[似乎有反爬机制]  >> 确认其加密后百度搜索\n",
    "# rct = requests.post('https://music.163.com/weapi/comment/resource/comments/get', headers=headers, params=params, data=data) \n",
    "# hotComments = rct.json()['data']['hotComments']\n",
    "# for hotComment in hotComments:\n",
    "#     print(hotComment['content'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "output_type": "stream",
     "name": "stderr",
     "text": [
      "D:\\software\\Python\\conda\\Lib\\site-packages\\urllib3\\connectionpool.py:988: InsecureRequestWarning: Unverified HTTPS request is being made to host '127.0.0.1'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings\n",
      "  InsecureRequestWarning,\n",
      "史上最负能量歌曲，不过悲剧才是真艺术\n",
      "希望每个人死后尸体都能自动变成一本书，书的内容就是死者的生平。这样一来，有人成了名著，有人成了禁书，有人变成菜谱，有人变成地图，有人是美图秀秀使用手册，有人是小旅馆的登记簿……整个世界就是一个巨大的图书馆，我们读着别人，做着自己，等着被读。\n",
      "天生脊椎有缺陷，医生不敢保证我能活到成年，然而 我挺过来了，身体却还是出现了问题  终于理解了 人定胜天这句话的可笑。。。  尚有些仗全力亦打不上。。。。\n",
      "不知道你们玩不玩DOTA 贴吧上的一个癌症晚期的dota玩家在2015年的时候他说他想看到中国队在2016总决赛插上中国的国旗 「夺冠的队伍能插上自己国家的国旗」今年WINGS做到了 兄弟 你看到了么？\n",
      "国语版的词也是尽力了\n",
      "想到妈妈去世的时候，躺在病床上，吸着呼吸机，毫无意识，亲手取下呼吸器，听着一旁的机器发出刺耳响声，眼前是妈妈安和平祥的样子，脑海里浮现着前一天晚上妈妈听到我叫她的时候，虚弱的冲我笑的样子。想哭又不敢，好像灵魂被撕裂一个的口子，我无能为力。妈妈去世快一百天了，我想她。\n",
      "歌词已纳入我墓志铭的备选铭文内\n",
      "高考复读听这首歌真是应景[大哭][大哭][大哭]\n",
      "E神脍炙人口的歌众多，但私以为这首传唱度并不高的歌是他最好听的没有之一，分享给大家，但是不知道歌的立意能不能被接受\n",
      "我一直觉得愿意跟另一个人分享自己的播放列表收藏的歌是一种很深的隐秘情谊 常用播放列表的音乐口味实在能披露太多东西了 你的性格 你的过往 你的暗处 你无法直陈的那些话 全都写在播放列表里 具有相似的音乐口味和具有相似的饮食口味 绝对可以成为衡量两个人是否可以久处不厌的重要标准\n",
      "小时候看过一部动画片，每集结束时“the end”的配音是“演完了”。\n",
      "谁能听出来   开头有个深深的叹息\n",
      "这歌词每一句都能断章取义，脑补出1W字的大长篇虐文[流泪] 。\n",
      "我喜欢听这首看起来轻描淡写的歌曲。\n",
      "12年刚出的时间经常听，13年倒下那次以为自己要死了之后更是一直一直听着这首反复思考，虽然身体每况愈下但是却听的少了。那段时间签名变成了这首的一些句子和《富士山下》的“人活到几岁算短……”[大哭]\n",
      "0\n"
     ]
    }
   ],
   "source": [
    "# 百度借鉴的例程\n",
    "import requests\n",
    "import json\n",
    "import base64\n",
    "import random\n",
    "import time\n",
    "from Crypto.Cipher import AES\n",
    "\n",
    "param2 = \"010001\"\n",
    "param3 = \"00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7b725152b3ab17a876aea8a5aa76d2e417629ec4ee341f56135fccf695280104e0312ecbda92557c93870114af6c9d05c4f7f0c3685b7a46bee255932575cce10b424d813cfe4875d3e82047b97ddef52741d546b8e289dc6935b3ece0462db0a22b8e7\"\n",
    "param4 = \"0CoJUm6Qyw8W8jud\"\n",
    "\n",
    "def AES_encrypt(text, key, iv):\n",
    "    pad = 16 - len(text) % 16\n",
    "    text = text + pad * chr(pad)\n",
    "    text = text.encode(\"utf-8\")\n",
    "    encryptor = AES.new(key.encode('utf-8'), AES.MODE_CBC, iv)\n",
    "    encrypt_text = encryptor.encrypt(text)\n",
    "    encrypt_text = base64.b64encode(encrypt_text)\n",
    "    return encrypt_text.decode('utf-8')\n",
    "\n",
    "def asrsea(p1, p2, p3, p4):\n",
    "    res = {}\n",
    "    rand_num = \"aq9d7cvBOJ1tzj1o\"\n",
    "    vi = b\"0102030405060708\"\n",
    "    h_encText = AES_encrypt(p1, p4, vi)\n",
    "    h_encText = AES_encrypt(h_encText, rand_num, vi)\n",
    "    res[\"encText\"] = h_encText\n",
    "    res[\"encSecKey\"] = \"5dec9ded1d7223302cc7db8d7e0428b04139743ab7e3d451ae47837f34e66f9a86f63e45ef20d147c33d88530a6c3c9d9d88e38586b42ee30ce43fbf3283a2b10e3118b76e11d6561d80e33ae38deb96832b1a358665c0579b1576b21f995829d45fc43612eede2ac243c6ebb6c2d16127742f3ac913d3ac7d6026b44cee424e\"\n",
    "    return res\n",
    "\n",
    "# for i in range(11):\n",
    "i = 0\n",
    "curr_time = int(time.time() * 1000)\n",
    "param1 = json.dumps({\"csrf_token\": \"\", \"cursor\": \"%s\" % curr_time, \"offset\": str(i*20), \"orderType\": \"2\", \"pageNo\": str(i+1),\n",
    "                        \"pageSize\": \"20\", \"rid\": \"R_SO_4_64048\", \"threadId\": \"R_SO_4_64048\"})\n",
    "\n",
    "asrsea_res = asrsea(param1, param2, param3, param4)\n",
    "\n",
    "url = \"https://music.163.com/weapi/comment/resource/comments/get?csrf_token=\"\n",
    "\n",
    "param_data = {\"params\": asrsea_res[\"encText\"],\n",
    "                \"encSecKey\": asrsea_res[\"encSecKey\"]}\n",
    "\n",
    "rct = requests.post(url, headers=headers, data=param_data, verify=False)\n",
    "hotComments = rct.json()['data']['hotComments']\n",
    "for hotComment in hotComments:\n",
    "    print(hotComment['content'])\n",
    "# break\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "if 1 is 3 or 2:\n",
    "    print('s')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ]
}